package com.hqd.ch03.v36.web.servlet.handler;


import com.hqd.ch03.v36.aware.BeanNameAware;
import com.hqd.ch03.v36.core.Ordered;
import com.hqd.ch03.v36.web.servlet.HandlerExecutionChain;
import com.hqd.ch03.v36.web.servlet.HandlerInterceptor;
import com.hqd.ch03.v36.web.servlet.HandlerMapping;
import com.hqd.ch03.v36.web.utils.UrlPathHelper;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public abstract class AbstractHandlerMapping implements HandlerMapping, BeanNameAware, Ordered {
    private final List<HandlerInterceptor> adaptedInterceptors = new ArrayList<>();
    private final List<Object> interceptors = new ArrayList<>();
    /**
     * 默认处理器
     */
    private Object defaultHandler;
    private UrlPathHelper urlPathHelper = new UrlPathHelper();
    private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered

    private String beanName;

    @Override
    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        //具体获取方式由子类实现
        Object handler = getHandlerInternal(request);
        if (handler == null) {
            handler = getDefaultHandler();
        }
        if (handler == null) {
            return null;
        }
        return getHandlerExecutionChain(handler, request);
    }

    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
                (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

        for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
            chain.addInterceptor(interceptor);
        }
        return chain;
    }

    public void initInterceptors() {
        if (!this.interceptors.isEmpty()) {
            for (int i = 0; i < this.interceptors.size(); i++) {
                Object interceptor = this.interceptors.get(i);
                if (interceptor == null) {
                    throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
                }
                this.adaptedInterceptors.add(adaptInterceptor(interceptor));
            }
        }
    }

    protected String initLookupPath(HttpServletRequest request) {
        return getUrlPathHelper().resolveAndCacheLookupPath(request);
    }

    protected HandlerInterceptor adaptInterceptor(Object interceptor) {
        if (interceptor instanceof HandlerInterceptor) {
            return (HandlerInterceptor) interceptor;
        } else {
            throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName());
        }
    }

    public void setInterceptors(Object... interceptors) {
        this.interceptors.addAll(Arrays.asList(interceptors));
    }

    protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;

    public UrlPathHelper getUrlPathHelper() {
        return urlPathHelper;
    }


    public Object getDefaultHandler() {
        return this.defaultHandler;
    }

    public void setDefaultHandler(Object defaultHandler) {
        this.defaultHandler = defaultHandler;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }
}
